<?php	if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * History Class
 *
 * Saves the users browsing history into their session.
 *
 * @licence 	MIT Licence
 * @category	Models
 * @author  	Simon Stenhouse
 * @link    	http://stensi.com
 * @version 	1.0
 */
class History {

	var $CI;
	var $save_auto = TRUE;
	var $save_ajax = FALSE;
	var $default_page = '';
	var $length = 10;

	/**
	 * Constructor
	 *
	 * Initialize controller.
	 */
	function History($config = array())
	{
		$this->CI =& get_instance();

		// Store config settings
		foreach ($config as $key => $value)
		{
			$this->{$key} = $value;
		}

		$this->CI->load->library('session');

		// Get history
		$history = $this->_get_history();

		// If history is empty
		if (empty($history))
		{
			// Prepopulate it with the default page
			for ($i = 0; $i < $this->length; $i++)
			{
				$history[$i] = $this->default_page;
			}

			// Update session
			$this->CI->session->set_userdata('history', $history);
		}

		// Save current page into history if auto saving is on
		if ($this->save_auto)
		{
			$this->save();
		}
	}

	// --------------------------------------------------------------------

	/**
	 * Get
	 *
	 * Gets the url of the current page or the specified number of pages back in the history.
	 * Optionally return an array of the history, from the oldest page, up to the current page
	 * or the specified number of pages back in the history.
	 *
	 * @access	public
	 * @param	string
	 * @param	bool
	 * @return	mixed
	 */
	function get($pages = 0, $as_array = FALSE)
	{
		// Get history
		$history = $this->_get_history();

		if ($pages > 0)
		{
			// Ensure pages is in range
			if ($pages > $this->length)
			{
				$pages = $this->length;
			}

			// Go back the specified number of pages, removing pages from the history as we go
			$history = array_slice($history, 0, $this->length - $pages);

			// Prepend the history with the default page to get it back up to its full length
			for ($i = 0; $i < $pages; $i++)
			{
				// Prepend the default page
				array_unshift($history, $this->default_page);
			}
		}

		// Check if array was requested
		if ($as_array)
		{
			// Return array of history
			return $history;
		}
		else
		{
			// Return url of page
			return array_pop($history);
		}
	}

	// --------------------------------------------------------------------

	/**
	 * Save
	 *
	 * Saves the url of the current page or a specified url into the history.
	 *
	 * @access	public
	 * @param	string
	 * @return	bool
	 */
	function save($url = '')
	{
		// If url not specified, determine the url of the current page
		if ($url == '')
		{
			// From the Request URI
			if ($_SERVER['REQUEST_URI'])
			{
				// Remove forward slash from start of url
				$url = strpos($_SERVER['REQUEST_URI'], '/') !== FALSE ? substr($_SERVER['REQUEST_URI'], 1) : $_SERVER['REQUEST_URI'];
			}
			else
			{
				// Set as the default page
				$url = $this->default_page;
			}
		}

		// Return if the url is the same as the last one or,
		// if we're not saving AJAX requests, if it was an AJAX request
		if ($url == $this->get() || !$this->save_ajax && $this->_is_ajax())
		{
			return FALSE;
		}

		// Get history
		$history = $this->_get_history();

		// Shift the first value off the array
		array_shift($history);

		// Push the new value onto the end of the array
		array_push($history, $url);

		// Update session
		$this->CI->session->set_userdata('history', $history);

		return TRUE;
	}

	// --------------------------------------------------------------------

	/**
	 * Delete
	 *
	 * Deletes the current page or the specified number of pages back in the history.
	 *
	 * @access	public
	 * @param	string
	 * @return	string
	 */
	function delete($pages = 0)
	{
		// Ensure pages is in range
		if ($pages < 0)
		{
			$pages = 0;
		}

		// Increase pages to start from correct point
		$pages++;

		// Get history
		$history = $this->get($pages, TRUE);

		// Update session
		$this->CI->session->set_userdata('history', $history);

		// Return url of page we've deleted up to
		return array_pop($history);
	}

	// --------------------------------------------------------------------

	/**
	 * Back
	 *
	 * Redirects the user back to the previous page or the specified number of pages into their history.
	 *
	 * @access	public
	 * @param	int
	 * @return	void
	 */
	function back($pages = 1)
	{
		// Redirect back the specified number of pages
		redirect($this->delete($pages));
	}

	// --------------------------------------------------------------------

	/**
	 * Get History
	 *
	 * Gets the history from the session.
	 *
	 * @access	private
	 * @return	array
	 */
	function _get_history()
	{
		// Get history
		$history = $this->CI->session->userdata('history');

		// Make sure history is an array
		if (empty($history) || !is_array($history))
		{
			$history = array();
		}

		return $history;
	}

	// --------------------------------------------------------------------

	/**
	 * Is AJAX
	 *
	 * Determines whether the request was sent via AJAX.
	 *
	 * @access	private
	 * @return	bool
	 */
	function _is_ajax()
	{
		return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest');
	}
}